using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace SharePointRsync
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    [Guid("7fa94a31-3c13-4ef8-859f-ab457f4aaac9")]
    public class SyncList : SPFeatureReceiver
    {
        private string jobName;

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPWeb web = properties.Feature.Parent as SPWeb;
            jobName = "Sync List Timer Management for " + web.Title;
            try
            {
                deleteJob(web, jobName);
                SetUpSyncJob(web);
            }
            catch (SPException ex)
            {
                throw new SPException(ex.Message);
            }
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPWeb web = properties.Feature.Parent as SPWeb;
            web.Lists["Sync List Timer Management"].Delete();
            deleteJob(web, "Sync job for");
            deleteJob(web, "Sync List Timer Management for " + web.Title);
        }

        private string createSyncList(SPWeb web)
        {
            try
            {
                Guid syncListID = web.Lists.Add("File Sync Control", "This list controls file synchronization to the SharePoint extranet", SPListTemplateType.GenericList);

                SPList syncList = web.Lists[syncListID];
                SPFieldCollection fields = syncList.Fields;

                syncList.EnableSyndication = true;
                syncList.OnQuickLaunch = true;
                syncList.ContentTypesEnabled = true;
                syncList.EnableAttachments = false;
                syncList.EnableVersioning = true;
                syncList.MajorVersionLimit = 20;
                syncList.NoCrawl = true;

                SPContentTypeId syncJobCTID = new SPContentTypeId("0x01009C703949A1AE054580E048B68B70E934");
                SPContentType syncJobCT = web.AvailableContentTypes[syncJobCTID];
                syncList.ContentTypes.Add(syncJobCT);
                syncList.ContentTypes.Delete(syncList.ContentTypes["Item"].Id);

                SPView defaultView = syncList.DefaultView;
                defaultView.ViewFields.DeleteAll();
                defaultView.ViewFields.Add("LinkTitle");
                defaultView.ViewFields.Add("Sync From");
                defaultView.ViewFields.Add("Sync To");
                defaultView.ViewFields.Add("Create Zip");
                defaultView.ViewFields.Add("Sync Status");
                defaultView.ViewFields.Add("Last Sync");
                defaultView.ViewFields.Add("Sync Log");
                defaultView.Update();

                syncList.Update();

                return syncList.DefaultViewUrl;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        private void SetUpSyncJob(SPWeb web)
        {

            string listID = createManagementList(web);

            SyncJobManager syncJobManager = new SyncJobManager(jobName, SPFarm.Local.TimerService, web.Url);

            SPMinuteSchedule schedule = new SPMinuteSchedule();
            schedule.BeginSecond = 0;
            schedule.EndSecond = 0;
            schedule.Interval = 5;
            syncJobManager.Schedule = schedule;
            syncJobManager.Title = jobName;

            syncJobManager.Update();
        }

        private string createManagementList(SPWeb web)
        {
            Guid managmentListID = web.Lists.Add("Sync List Timer Management", "This list controls the timers associated with the file Synchronization lists.", SPListTemplateType.GenericList);

            SPList managmentList = web.Lists[managmentListID];
            SPFieldCollection fields = managmentList.Fields;

            managmentList.EnableSyndication = true;
            managmentList.OnQuickLaunch = true;
            managmentList.ContentTypesEnabled = true;
            managmentList.EnableAttachments = false;
            managmentList.EnableVersioning = true;
            managmentList.MajorVersionLimit = 20;
            managmentList.NoCrawl = true;

            managmentList.Fields.Add("Sync List", SPFieldType.URL, true);
            managmentList.Fields.Add("Sync Type", SPFieldType.Choice, true);
            SPFieldMultiChoice syncType = (SPFieldMultiChoice)web.Lists["Sync List Timer Management"].Fields["Sync Type"];
            syncType.Choices.Add("Daily");
            syncType.Choices.Add("Hourly");
            syncType.Update();
            managmentList.Fields.Add("Start Hour", SPFieldType.Integer, true);
            managmentList.Update();

            SPView defaultView = managmentList.DefaultView;
            defaultView.ViewFields.Add("Sync List");
            defaultView.ViewFields.Add("Sync Type");
            defaultView.ViewFields.Add("Start Hour");
            defaultView.ViewFields.Add("Modified");
            defaultView.ViewFields.Add("Editor");
            defaultView.Update();

            string listUrl = "";

            try
            {
                listUrl = web.Lists["File Sync Control"].DefaultViewUrl;
            }
            catch
            {
                listUrl = createSyncList(web);
            }

            SPListItem firstItem = managmentList.Items.Add();
            firstItem["Title"] = "Initial Sync List";
            firstItem["Sync List"] = listUrl;
            firstItem["Sync Type"] = "Daily";
            firstItem["Start Hour"] = 2;
            firstItem.Update();

            return managmentList.ID.ToString();
        }

        public static void deleteJob(SPWeb web, string jobNameSearchString)
        {
            foreach (SPJobDefinition job in web.Site.WebApplication.JobDefinitions)
            {
                if (job.Name.StartsWith(jobNameSearchString))
                {
                    job.Delete();
                }
            }
        }
    }
}
